package com.example.demo.service;

import com.riku.security.core.SeAuthorityService;
import com.riku.security.core.SeExternalUserService;
import com.riku.security.model.SeUserParam;
import com.riku.security.service.SeCommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by 1 on 2021/6/2.
 */
@Service
public class AutorityServiceImpl implements SeAuthorityService{

    @Autowired
    private SeCommonService seCommonService;
    @Autowired
    private SeExternalUserService seExternalUserService;
    /**
     * 系统启动时会按serviceCode载入这些service的api列表,当接口调用时,如果url地址存在于载入的api列表,
     * 就会去取getPathsFromCache的个人权限进行比对拦截
     * 如果service的部分接口地址不需要拦截,就不要把接口配到菜单里
     * 如果整个service的接口都不需要拦截,此处就不要build进来
     * @return
     */
    @Override
    public String[] buildServicePath() {
        String []codes = {"security","test"};

        return codes;
    }

    /**
     * 白名单的不进行拦截，当然buildServicePath规定之外的路径本身就不会拦截。
     * 1.指定对build进来的service的接口，其中哪些不需要拦截 2.有些整体不需要拦截的可通过白名单避免多余无效的匹配过程
     * @return
     */
    @Override
    public String[] buildWhiteList() {
        return new String[0];
    }

    /**
     * 每次系统进行接口调用时会判断权限，每次都会调用此接口获取用户的权限，不应每次查库
     * 此处为测试。应在登录时调用getApiSecurityForLogin获取权限后放入缓存，并在此处从缓存取数,不然每次查数据库获取权限效率太低
     * @return
     */
    @Override
    public List<Long> getPathsFromCache() {
        return seCommonService.getApiSecurityForLogin(seExternalUserService.getNowUser().getUserId(),buildServicePath());
    }

    /**
     * 当进行接口调用时，告诉系统当前的api地址属于哪个service，可通过threadlocal或者session返回
     * 如果不告知，会对载入的所有service的地址进行比对,会多耗时间
     * 例:此处传security,调用接口时就会将url与security服务的api列表比对,若存在则接下来需要去判断用户权限,不存在则不需要判断权限
     * @return
     */
    @Override
    public String getCurrentServiceCode() {
        return "security";
    }
}
